系列說明 >> 本系列大部分 PR 來自私人或公司專案,部分程式碼、環境設定與實作細節不便公開。
我只能保證文中提到的 PR 與問題皆為真實案例,但會經過必要的匿名化與內容調整。
本系列主要分享問題如何被發現、背後的思考方式,以及解法如何形成,不會深入討論完整實作與部署細節,敬請見諒。
Base Repo: paulshaclaw
Change Ref: PR #217-feat(deck): W0 Card/Combo schema 基座與契約對齊 → #224-feat(deck): 實作 W3 compile 與 CLI lane → #229-test(deck): W7 整合驗證與 Phase A 收尾,背景 Issue #186-skill/persona 卡片化,以組合技完成 task 交辦
Issue: feature-delivery-pipeline 已經把 Feature 從 Planning、Build、Review、Verify 到 Ship 的工作方式寫成 Skill,但每換一個 Agent,Operator 仍可能要重新提醒哪些 Phase 不能跳、哪些 Artifact 必須留下;真正派工時,也仍要人工把這套工作方法拆成多份 Runtime Spec。
Root Cause: 可重用 Workflow 仍停留在給人與 Agent 閱讀的文字,沒有成為 Runtime 可以直接驗證與消費的 Machine-readable Artifact。Execution Engine 已經能處理 depends_on、Fanout 與下游 Release,但中間缺少一層把「這類工作通常怎麼走」轉成正式工作單位。
Solution: 建立 Deck 宣告層。Card 描述可重用工作單位,Combo 描述 Card 的組合與 Dependency,再由 Compiler 將 task + combo 展開成 Manager 可讀的 Slice Specs;預設 Dry-run,--emit 也只產生 dispatch: hold,不順便替 Runtime 決定何時開工。
Evidence: Phase A 完成 Card/Combo Schema、Contract Alignment 與 Compiler;乾淨環境可列出 2 combos / 12+ cards,feature-oneshot 可編譯成 5 份 Hold Specs,Dry-run 零落地,Missing Output 時 deck verify Exit 1。PR #229 記錄 1781 passed、7 個既有環境 Failure、Policy Check 零 Fail;自主選牌與自動 Dispatch 仍屬後續。
上一篇最後,小pa把十個 Task 拆好了。
十個小bu一起舉手:
「我來。」
很好。
至少「到底要做什麼」這件事,這次說清楚了。
而且 Feature 要怎麼一路從 Build 走到 Review、Verify、Ship,我其實也不是第一次做。
我早就有一套 feature-delivery-pipeline。
裡面連哪個階段該留下什麼 Artifact、什麼時候不能讓 Builder 自己說 Pass,都已經寫過。
所以我很自然地把其中一個 Task 丟給小bu:
「照 Feature Delivery Pipeline 跑。」
小bu看完 Plan,很快回了一句:
「了解,我先改 Code。」
「等一下,前面的 Spec 呢?」
「這個修改很小,需求也很清楚,可以直接做。」
「那 Review?」
「Build 完一起。」
「Verify 呢?」
「Test 過應該就可以——」
停。
這段對話我怎麼好像看過?
我把流程重新講一遍,小bu也很配合地補回去。
第一個 Task 總算正常往下走。
然後我換了另一隻 Agent。
它沒有直接跳 Build。
很好,有進步。
它只是把 Review 跟 Verify 合在一起,順便覺得最後的對抗審查這次應該可以省。
我又講了一次。
第三隻 Agent 更乖,前面都照做。
做到後面卻忘了留下下一階段要吃的 Artifact。
我再提醒一次。
十個小bu本來是來幫我分工的。
跑到第三個,我又開始逐條確認:
這步有沒有走?
Artifact 有沒有留下?
下一步現在能不能放?
這個 Gate 真的過了嗎?
老Go看了一陣子。
「所以你多開十個 Agent,是為了讓自己當十次導遊?」
……好問題。
feature-delivery-pipeline 其實是我在多次下達任務、執行prompt後提煉出來的Skill,
它會告訴 Agent:
這個 Feature 要用什麼skill build up
要怎麼 Planning
用哪一種方式 Review
哪裡要 Verify
哪些地方需要獨立 Gate
Agent 看得懂,也能依當下情境調整。
這本來是優點。
前面的 Planning 可能反覆好幾輪,某些 Task 也確實不需要把十一個 Phase 一格一格硬走完。
真正麻煩的是,我一直分不清楚:
這次少一個 Step,是經過明確決策後的調整?
還是 Agent 做到一半覺得差不多了,自己把 Pipeline 縮短?
只要 Workflow 還主要靠「讀懂這篇 Skill」,答案就很依賴當下那隻 Agent 怎麼理解。
換一隻,理解就可能換一版。
而我則負責把它們一隻一隻拉回來。
小re問了一句:
「你現在到底是在檢查結果,還是在提醒流程?」
我想了一下。
兩個都有。
這就不太妙了。
Review 應該檢查工作做得對不對。
如果我還得順便負責提醒「下一步本來就應該存在」,表示有些規則根本還沒進到系統裡。
老樣子,用我普通工程師直覺,見山是山,見招拆招。
既然 Agent 老是跳,那我就在 Skill 裡寫清楚:
這步不准跳。
那步一定要做。
Review 前必須怎樣。
Verify 後才能怎樣。
小bu看了一眼。
「可以,我照表做。」
嗯。
問題解決。
大概維持了五秒。
因為 Planning 本來就不是每次都走同一條直線。
有些 Issue 一開始連問題邊界都還沒搞清楚,可能要在 Spec 跟 Plan 之間來回好幾次;有些修改已有完整 Spec,根本不需要再重新 Brainstorm 一輪。
如果我把每一種情況全部寫進 Skill,最後會得到一篇:
如果 A,走 B。
除非 C,此時改走 D。
但遇到 E 時,請參考第七節第三項……
恭喜。
我成功把 Agent Workflow 寫成所得稅申報說明。
小re這時反而問了一個比較有用的問題:
「你真正不想讓它跳掉的是哪一部分?」
我想了一下。
其實我不是在意小bu每一步到底怎麼想。
我在意的是:
該有的 Plan 有沒有留下?
Build 需要的 Input 到了沒有?
Review 到底有沒有發生?
Verification 有沒有 Evidence?
下一步需要的 Artifact 到底存不存在?
Agent 中間怎麼繞,有些地方可以讓它自己決定。
但後面的角色要吃什麼、前面的工作要留下什麼,不能每換一隻 Agent 就重新解釋一次。
問題開始進入見山不是山的境界了。
我需要固定的不是:
Agent 每一步應該怎麼走。
而是:
這類工作有哪些不能消失的工程交接點。
回頭看 feature-delivery-pipeline,其實裡面一直有一些重複出現的工作。
例如:
writing-plan
build
code-review
verification
adversarial-review
它們每次處理的內容不同,但工作形狀很像。
以 code-review 來說,我至少希望系統知道:
開始前
→ 應該已經有可 Review 的變更
做完後
→ 應該留下 Review 結果
至於 Reviewer 中間怎麼讀 Code、先查哪個檔案、要不要多跑一個 Command,可以留給 Agent。
這種可重用的工作單位,後來叫 Card。
一張 Card 不需要把整個 Skill 複製進去。
它只把真正需要跨角色交接的東西拉出來:
這是什麼工作。
需要什麼。
完成後產生什麼。
通常由哪種 Persona/Skill 處理。
有了 Card,接下來就可以描述:
一般 Feature 到底由哪些 Card 組成?
例如:
build
→ code-review
→ verification
→ ship
→ adversarial-review
這個具名組合就叫 Combo。
小pa還是負責「這次要做什麼」。
Combo 則回答:
「這一類工作,通常有哪些工程交接點?」
兩件事終於沒有混在一起。
Card/Combo 的概念確定後,才需要真的把它存成程式能讀的東西。
一招鮮,吃遍天,好用的YAML又可以拿出來用了。
例如一個 Combo 大概像:
combo:
id: feature-oneshot
cards:
- ref: build
- ref: code-review
depends_on: [build]
- ref: verification
depends_on: [code-review]
現在這份 YAML 的身分就很單純了。
它不是小pa替某個 Issue 寫的 Plan。
也不是拿來告訴 Agent每一步怎麼思考。
它只是在記:
這套可重用 Workflow 有哪些 Card,以及它們彼此怎麼接。
既然後面真的會拿這份東西去產生工作,Deck 第一件事也不是幫我把 Agent 全放出去。
而是先檢查這份宣告到底能不能信。
例如:
- ref: code-reveiw
拼錯一個字。
人類一眼就知道大概是 code-review。
小bu也很樂意幫忙猜。
Deck 不行。
不存在就是拒絕。
因為這已經不是文件錯字。
後面真的有人會等這張 Card 的產出。
現在幫它「猜一下」,幾步之後就是另外一隻 Agent 在猜為什麼上游永遠沒有完成。
Card/Combo 能被可靠讀取後,下一步才是 Compile。
輸入從以前的:
「照 Feature Delivery 跑。」
變成比較明確的:
這個 Task
+
feature-oneshot 這張 Combo
Deck 再把它展開成既有 Runtime 已經會處理的 Slice Specs。
但第一版仍然刻意踩煞車。
預設只 Dry-run。
真的 --emit,產出的 Spec 也全部先是:
dispatch: hold
也就是:
工作單已經寫好了。
但現在能不能開工,我還沒替你決定。
這個 Boundary 我很喜歡。
因為 Deck 解的是:
「這套工作方法如何變成正式 Artifact?」
不是:
「現在到底該不該派 Agent?」
兩件事很容易一起做。
一起做也很容易出事。
Phase A 最後實走:
psc deck list
→ 2 combos / 12+ cards
psc deck compile
→ dry-run,零落地
psc deck compile --emit
→ 5 份 dispatch: hold specs
deck verify
→ 缺少宣告產出時 exit 1
這些 Evidence 能證明的事情很有限。
Card/Combo 已經可以描述一套可重用 Workflow。
Deck 可以把它翻成既有 Runtime 能接手的 Hold Specs。
宣告不存在的 Card,或該留下的 Artifact 不存在,也可以明確 Fail。
它還不會自己看一個 Task 就選 Combo。
不會挑 Agent。
更不會替我決定現在是不是該 Dispatch。
但至少 feature-delivery-pipeline 不再只是:
「希望下一隻 Agent 有好好讀完。」
Skill 還是 Skill。
Agent 仍然可以在允許的地方判斷、迭代、調整。
只是那些真的不能憑感覺消失的工程交接點,現在有另一份 Artifact 幫我守著。
不過 Deck 把 Spec 生出來之後,事情並沒有自己往下走。
誰要看 depends_on?
誰知道上游完成沒?
誰負責把 Hold 的工作真正往下一段送?
前面其實已經碰過那個名字幾次。
Coordinator。
這篇先不管它。
我只順著這些 Spec 往後看了一眼,然後發現 Persona、Coordinator、Control 全部還住在 paulshaclaw 裡。
老Go看了一下 Repo。
「你現在工作方法都開始拆責任了。」
「那跑 Workflow 的東西,還全部跟操作介面住一起?」
……
好。
下一個問題看起來已經自己找上門了。
而我第一個想到的搬家方法,依然非常有工程師傳統:
cp -r
下一篇,新 Repo 都建好了,Runtime 卻還在問舊家路怎麼走。
Have a nice day.